<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>

    /**
     * call()和apply()方法
     * 两个的区别：
     * call()和apply()方法都是调用函数的方法，
     * 但是它们有区别：
     *  1.参数传递方式：
     *      call()：接受的是单独的参数列表。
     *      apply()：接受的是一个数组或类数组对象。
     */
    function greet(name, age) {
        console.log("hello" + name + "，your age is" + age)
    }

    var persion = {
        name: "张三",
        age: 18
    };

    /**
     * call()方法
     * call() 方法调用一个函数，并且允许你为函数指定 this 值和传递多个参数。
     * 语法：function.call(thisArg, arg1, arg2, ...)
     * thisArg: thisArg 是一个必选参数，它指定了函数被调用时使用的 this 值。
     * arg1, arg2, ...: 一个可选参数列表，它指定了传递给函数的参数。
     */
    greet.call(persion, "张三", 18)


    /**
     * apply()方法
     * apply() 方法调用一个函数，并且允许你为函数指定 this 值和传递一个参数数组。
     * 语法：function.apply(thisArg, [arg1, arg2, ...])
     * thisArg: thisArg 是一个必选参数，它指定了函数被调用时使用的 this 值。
     * [arg1, arg2, ...]：一个包含多个参数的数组或类数组对象。
     */
    greet.apply(persion, ["李四", 18])


    /**
     * 调用函数时，实参都是保存在arguments中
     * 在调用函数时，每次都会传递两个参数：
     * -1.this 对象
     * -2.封装实参的对象arguments
     *    -arguments是一个类数组对象，可以通过索引操作数据，也可以获取长度
     *    -函数调用的参数都保存在arguments对象中
     *    -arguments.length用来获取实参的长度
     *    -即使不定义形参，也可以通过arguments获取实参
     *          -arguments[0]表示获取第一个实参
     *    -callee属性：当前执行的函数对象本身
     * arguments()方法
     */

    function fun() {
        // console.log(arguments instanceof Array) //检查是否是一个数组
        // console.log(Array.isArray(arguments)) //检查是否是一个数组
        // console.log(arguments.length); //获取实参的长度
        // console.log(arguments[0]) //获取实参
        console.log(arguments.callee) //获取当前正在执行的函数对象
    }

    fun("hello", true)
</script>

</body>
</html>
